<style>
	@import "/static/css/common.css";
	@import "/static/css/chat-chating.css";
</style>
<template>
	<view>
		<view class="game-container">
			<view class="score-board">
				<view class="team red-team">
					<view class="team-name">红方</view>
					<view class="team-score">{{ score.red }}</view>
				</view>
				<view class="vs">VS</view>
				<view class="team blue-team">
					<view class="team-score">{{ score.blue }}</view>
					<view class="team-name">蓝方</view>
				</view>
			</view>
			<view class="battlefield">
				<view v-for="(lane, i) in danmus" :key="i" class="lane">
					<view v-for="dm in lane" :key="dm.id" class="danmu" :style="dm.style">
						{{ dm.content }}
					</view>
				</view>
			</view>
			<view class="send-box">
				<input v-model="content" class="send-box__input" placeholder="发弹幕" />
				<button class="send-box__btn" @click="send">发送</button>
				<!-- <button class="send-box__btn" @click="send1">发送1</button> -->
			</view>
		</view>
		<view v-if="tip" class="tip-layer">
			<view class="tip">{{tipContent}}</view>
		</view>
	</view>
</template>

<script>
	import {
		showTips
	} from '@/static/js/common.js';

	export default {
		data() {
			return {
				WebSocketUrl: "ws://fengjian123.com/public/ws",
				// WebSocketUrl: "ws://localhost:8080/public/ws",
				httpUrl: "http://fengjian123.com:8080/",
				// httpUrl: "http://localhost:8080/",
				imgUrl: "https://www.fengjian123.com/",
				socketOpen: false,
				token: "",
				user: {
					userid: "",
					avatar: ''
				},
				tipContent: '',
				tip: 0,
				content: '',
				userSide: 'red', // 或 'blue'
				danmus: [
					[],
					[],
					[],
					[],
					[],
					[],
					[],
					[],
					[],
					[]
				],
				score: {
					red: 0,
					blue: 0
				},
				loop: null,
				lineup: 1,
			}
		},
		// 页面加载时触发
		onLoad(option) {
			this.getCookie();
		},
		//页面断开时触发
		onUnload() {
			this.close();
		},
		// 页面渲染结束后触发
		mounted() {
			this.$nextTick(() => {
				this.connect();
			});
			this.startLoop();
			this.getScore();
		},
		beforeDestroy() {
			clearInterval(this.loop);
		},
		methods: {
			// 连接服务端
			connect: function() {
				let _this = this;
				console.log("开始连接..." + "用户id：" + _this.user.userid + "用户token：" + _this.token);
				uni.connectSocket({ // 创建一个 WebSocket 连接
					url: _this.WebSocketUrl + "?userId=" + _this.user.userid,
					method: 'GET'
				});
				uni.onSocketOpen(function(res) { // 连接websocket成功
					_this.socketOpen = true;
					console.log('WebSocket连接已打开！');
				});
				uni.onSocketError(function(res) { // 连接websocket失败
					console.log('WebSocket连接打开失败，请检查！');
				});
				uni.onSocketMessage((res) => {
					let dm = JSON.parse(res.data);
					if (!this.danmus[dm.lane]) {
						console.warn('弹幕lane越界:', dm.lane);
						return;
					}

					dm.style =
						`left:${dm.position}%;transform:translateX(${dm.side==='red'?'0':'-100%'});color:${dm.side};top:50%;transform:translateY(-50%) translateX(${dm.side==='red'?'0':'-100%'});`;

					// 这样替换确保响应式更新
					const lane = [...this.danmus[dm.lane], dm];
					this.$set(this.danmus, dm.lane, lane);
					console.log('当前danmus:', JSON.stringify(this.danmus));
				});
				uni.onSocketClose(function(res) {
					// _this.connect();
					console.log('WebSocket 已关闭！');
				});
			},
			//关闭服务端
			close: function() {
				uni.closeSocket();
			},
			// 获取缓存
			getCookie: function() {
				let _this = this;
				uni.getStorage({
					key: 'cookie',
					success: function(res) {
						if (res.data.id && res.data.login) {
							_this.user.userid = res.data.id;
							_this.token = res.data.token;
							_this.user.avatar = res.data.avatar;
							_this.lineup = res.data.lineup;
							_this.userSide = res.data.lineup == 1 ? 'red' : 'blue';
						} else {
							uni.reLaunch({
								url: '/pages/index/index',
							});
						}
					},
					fail: function() {
						_this.toLogin();
					}
				});
			},
			// 发送弹幕
			send() {
				if (!this.content.trim()) {
					this.tips('弹幕内容不能为空');
					return;
				}

				// 限制4个字符（中文算1个字符）
				if (this.content.length > 4) {
					this.tips('弹幕内容不能超过4个字');
					return;
				}

				const lane = Math.floor(Math.random() * 10);
				// const lane = 4;
				const danmu = {
					id: Date.now() + '' + Math.random(),
					content: this.content,
					side: this.userSide,
					lane,
					position: this.userSide === 'red' ? 0 : 100,
					userid: this.user.userid
				};
				this.content = '';
				uni.sendSocketMessage({
					data: JSON.stringify(danmu)
				});
			},
			send1() {
				if (!this.content.trim()) {
					this.tips('弹幕内容不能为空');
					return;
				}

				// 限制4个字符（中文算1个字符）
				if (this.content.length > 4) {
					this.tips('弹幕内容不能超过4个字');
					return;
				}

				const lane = Math.floor(Math.random() * 10);
				// const lane = 4;
				const danmu = {
					id: Date.now() + '' + Math.random(),
					content: this.content,
					side: 'blue',
					lane,
					position: 100,
					userid: this.user.userid
				};
				this.content = '';
				uni.sendSocketMessage({
					data: JSON.stringify(danmu)
				});
			},
			// 发送消息到websocket
			sendSocketMessage: function(msg) {
				let _this = this;
				if (_this.socketOpen) {
					uni.sendSocketMessage({
						data: msg
					});
				} else {
					socketMsgQueue.push(msg);
				}
			},
			// 推送弹幕
			addChat: function(bullettype = 0, bulletr = {}, bullethit = {}) {
				let _this = this;
				uni.request({
					url: _this.httpUrl + 'public/bullet',
					method: 'POST',
					header: {
						'Content-Type': 'application/json',
					},
					data: {
						bullettype: bullettype,
						bulletr: bulletr,
						bullethit: bullethit,
					},
					success: (res) => {
						// console.log(res);
					},
					fail: (res) => {
						console.log(res);
					},
				});
			},
			// 启动动画循环
			startLoop() {
				this.loop = setInterval(() => {
					const newDanmus = [
						[],
						[],
						[],
						[],
						[],
						[],
						[],
						[],
						[],
						[]
					]; // 构造新数组触发响应

					this.danmus.forEach((lane, i) => {
						let red = lane.filter(d => d.side === 'red');
						let blue = lane.filter(d => d.side === 'blue');

						red.forEach(r => {
							r.position += 1;
							r.style =
								`left:${r.position}%; transform:translateX(0); color:red; top:50%; transform:translateY(-50%);`;
						});

						blue.forEach(b => {
							b.position -= 1;
							b.style =
								`left:${b.position}%; transform:translateX(-100%) translateY(-50%); color:blue; top:50%;`;
						});

						// 简单碰撞
						red = red.filter(r => {
							const hit = blue.find(b => Math.abs(r.position - b.position) < 50);
							if (hit) { // 碰撞
								blue.splice(blue.indexOf(hit), 1);
								const bullettype = 0;
								const bulletr = {
									content: r.content,
									side: r.side,
									userid: r.userid,
								};
								const bullethit = {
									content: hit.content,
									side: hit.side,
									userid: hit.userid,
								};
								this.addChat(bullettype, bulletr, bullethit);
								this.getScore();
								return false;
							}
							if (r.position >= 100) { // 红成功
								const bullettype = 1;
								const bulletr = {
									content: r.content,
									side: r.side,
									userid: r.userid,
								};
								this.addChat(bullettype, bulletr);
								this.getScore();
								return false;
							}
							return true;
						});
						blue = blue.filter(b => {
							if (b.position <= 0) { // 蓝成功
								const bullettype = 1;
								const bulletr = {
									content: b.content,
									side: b.side,
									userid: b.userid,
								};
								this.addChat(bullettype, bulletr);
								this.getScore();
								return false;
							}
							return true;
						});

						newDanmus[i] = [...red, ...blue];
					});

					// 触发响应式更新
					this.danmus.forEach((lane, i) => {
						this.$set(this.danmus, i, newDanmus[i]);
					});
				}, 50);
			},
			// 获取分数
			getScore: function() {
				let _this = this;
				uni.request({
					url: _this.httpUrl + 'private/score',
					method: 'GET',
					header: {
						'Content-Type': 'application/json',
						'Authorization': 'Bearer ' + _this.token,
					},
					success: (res) => {
						if (res.data.err == 0) {
							_this.score.red = res.data.redscore;
							_this.score.blue = res.data.bluescore;
						}
					},
					fail: (res) => {
						console.log(res);
					},
				});
			},
			tips: function(content) {
				showTips(this, content);
			},
		}
	}
</script>